﻿using System;
using System . IO;
using System . Collections . Generic;
using System . Linq;
using System . Text;
using System . Reflection;
using System . Threading . Tasks;
using System . Runtime . CompilerServices;
using System . Timers;
using System . Collections . ObjectModel;
using OrangeEndless . Properties;
using System . Globalization;

namespace OrangeEndless
{
	[OrangeEndless . Mod ( "OrangeEndless" , "Wencey Wang" , "The Core Function For OrangeEndLess" , @"{00000001-0000-0000-0000-000000000001}" , new string [ ] { } )]
	public class OrangeEndlessCore : OrangeEndless . IMod
	{
		Timer Ticks;

		public static OrangeEndlessCore Current { get; set; }

		#region Orange

		#region Values

		public decimal NumberOfOrange { get; set; }

		public decimal SpeedOfOrangeRise { get; set; }

		public decimal NumberOfOrangeHaveProduce { get; set; }

		public decimal NumberOfOrangeHaveSell { get; set; }

		public decimal PriceOfOrange
		{
			get
			{
				return Convert . ToDecimal ( 1 / Math . Log ( Convert . ToDouble ( NumberOfMoney , CultureInfo . InvariantCulture ) , 100d ) , CultureInfo . InvariantCulture );
			}
		}

		#endregion

		#region Funcs

		public async Task<decimal> SellOrange ( decimal number )
		{
			return await Task . Run ( ( ) =>
			{
				decimal havesell = 0,haveget=0;
				for ( int i = 0 ; i < number && NumberOfOrange > 0 ; i++ )
				{
					NumberOfMoney += PriceOfOrange;
					haveget += PriceOfOrange;
					NumberOfOrange--;
					havesell++;
				}
				NumberOfOrangeHaveSell += havesell;
				NumberOfMoneyHaveGet += haveget;
				return havesell;
			} );
		}

		#endregion

		#endregion

		#region Money

		#region Values

		public decimal NumberOfMoney { get; set; }

		public decimal NumberOfMoneyHaveGet { get; set; }

		public decimal NumberOfMoneyHaveSpend { get; set; }

		#endregion

		#endregion

		#region Building

		#region Values

		public decimal NumberOfBuildingHaveBuy { get; private set; }

		public decimal NumberOfBuildingHaveSell { get; private set; }

		#endregion

		#region Collections

		public Collection<Building> ListOfBuilding { get; private set; }

		#endregion

		#region Funcs

		public async Task<decimal> BuyBuilding ( int index , decimal number )
		{
			return await Task . Run ( ( ) =>
			  {
				  decimal havebuy = 0,havespend=0;
				  for ( decimal i = 0 ; i < number && NumberOfMoney >= ListOfBuilding [ index ] . Price ; i++ )
				  {
					  NumberOfMoney -= ListOfBuilding [ index ] . Price;
					  havespend += ListOfBuilding [ index ] . Price;
					  ListOfBuilding [ index ] . Number++;
					  havebuy++;
				  }
				  NumberOfBuildingHaveBuy += havebuy;
				  NumberOfMoneyHaveSpend += havespend;
				  return havebuy;
			  } );
		}

		public async Task<decimal> SellBuilding ( int index , decimal number )
		{
			return await Task . Run ( ( ) =>
			{
				decimal havesell = 0,haveget=0;
				for ( int i = 0 ; i < number && ListOfBuilding [ index ] . Number > 0 ; i++ )
				{
					ListOfBuilding [ index ] . Number--;
					NumberOfMoney += ListOfBuilding [ index ] . Price;
					haveget+=ListOfBuilding [ index ] . Price;
					havesell++;
				}
				NumberOfBuildingHaveSell += havesell;
				NumberOfMoneyHaveGet += haveget;
				return havesell;
			} );
		}
		#endregion

		#endregion

		#region Technology

		#region Values

		public decimal NumberOfTechnologyHavePromoted { get; set; }

		#endregion

		#region Collections

		public Collection<Technology> ListOfTechnology { get; private set; }

		#endregion

		#region Funcs

		public async Task<bool> PromoteTechnology ( int index )
		{
			return await Task . Run ( ( ) =>
			{
				return true;
			} );
		}

		#endregion

		#endregion

		#region Achievement

		#region Value

		public decimal NumberOfAchievementHaveGet { get; set; }

		#endregion

		#region Collections
		public Collection<Achievement> ListOfAchievement { get; set; }

		#endregion

		#endregion

		public async Task Start ( )
		{
			var Ts=new List<Task> ( );
			Ts . Add ( Task . Run ( ( ) =>
			{
				for ( int i = 0 ; i <= 11 ; i++ )
				{
					ListOfBuilding . Add ( Building . LoadBuilding ( i ) );
				}
			} ) );

			await Task . WhenAll ( Ts );
			Ticks . Start ( );
		}

		public async Task Suspend ( )
		{
			Ticks . Stop ( );
			var Ts=new List<Task> ( );
			Ts . Add ( Task . Run ( ( ) =>
			{
				// NumberOfOrange 
			} ) );
			Ts . Add ( Task . Run ( ( ) =>
			{
				foreach ( var item in ListOfBuilding )
				{
					item . Suspend ( );
				}
			} ) );
			Ts . Add ( Task . Run ( ( ) =>
			{
				foreach ( var item in ListOfAchievement )
				{
					item . Suspend ( );
				}
			} ) );
			Ts . Add ( Task . Run ( ( ) =>
			{
				foreach ( var item in ListOfTechnology )
				{
					item . Suspend ( );
				}
			} ) );
			await Task . WhenAll ( Ts );
			Settings . Default . Save ( );
		}

		public async void Tick ( object sender , ElapsedEventArgs e )
		{
			var Ts=new List<Task> ( );

			Ts . Add ( Task . Run ( ( ) =>
			{
				decimal speed=0;
				foreach ( var item in ListOfBuilding )
				{
					NumberOfOrange += item . Cps;
					NumberOfOrangeHaveProduce += item . Cps;
					speed += item . Cps;
				}
				SpeedOfOrangeRise = speed;
			} ) );
			Ts . Add ( Task . Run ( ( ) =>
			{
				foreach ( var item in ListOfAchievement )
				{
					item . Check ( );
				}
			} ) );
			Ts . Add ( Task . Run ( ( ) => { } ) );
			await Task . WhenAll ( Ts );
		}

		public OrangeEndlessCore ( List<IMod> demend , Core core )
		{
			ListOfBuilding = new Collection<Building> ( );
			Ticks = new Timer ( 1000 );
			Ticks . AutoReset = true;
			Ticks . Enabled = true;
			Ticks . Elapsed += Tick;
		}

	}
}
